﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using TemplateWeb.Models;
using TemplateWeb.Models.ViewModels;
using TemplateWeb.Helpers;
using System.Data.Objects;
using System.Text;

namespace TemplateWeb.Controllers
{

    [HandleError]
    public class AccountController : BaseController
    {

        public IFormsAuthenticationService FormsService { get; set; }
        public IMembershipService MembershipService { get; set; }

        protected override void Initialize(RequestContext requestContext)
        {
            if (FormsService == null) { FormsService = new FormsAuthenticationService(); }
            if (MembershipService == null) { MembershipService = new AccountMembershipService(); }

            base.Initialize(requestContext);
        }

        // **************************************
        // URL: /Account/LogOn
        // **************************************

        public ActionResult LogOn()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult LogOn(FormCollection forms)
        {
            var errText = string.Empty;
            string username = forms.GetValues("LogOn_UserName")[0];
            string password = forms.GetValues("LogOn_Password")[0];

            ObjectParameter parpassword = new ObjectParameter("Password", typeof(string));
            ObjectParameter parsalt = new ObjectParameter("Salt", typeof(string));
            ObjectParameter parresult = new ObjectParameter("Result", typeof(int));
            var intResult = DataContext.Instance.selMembersLogin(username, parpassword, parsalt, parresult);
            if (intResult == -1)
            {
                errText = "Tài khoản này không tồn tại. Bạn có thể Đăng ký một Tài khỏan mới";
            }
            else if (intResult == -2)
            {
                errText = "Hệ thống hiện nay chưa cho phép đăng nhập vào diễn đàn.";
            }
            else if (intResult == -3)
            {
                errText = "Tài khoản của bạn đã bị khóa. Bạn không được phép đăng nhập vào diễn đàn.";
            }
            else if (intResult == -5)
            {
                errText = "Tài khoản của bạn chưa kích hoạt. Email kích hoạt Tài khoản đã được gửi đến Email bạn dùng đăng ký.";
            }
            else if (intResult == -4)
            {
                errText = "Tài khoản của bạn cần chờ duyệt trước khi đăng nhập vào diễn đàn.";
            }

            if (errText == string.Empty)
            {
                UtiHashMd5 md5 = new UtiHashMd5();
                // First hash password which user input
                password = md5.Md5Encode(password);
                // Then continue hash on above hashed password
                string strMd5Server = md5.Md5Encode(password + parsalt.Value);
                if (strMd5Server == parpassword.Value.ToString())
                {
                    var role = _repSLM_Members.SelectByUserName(username).SLM_Groups.FirstOrDefault(p => p.GroupId == 5 || p.GroupId == 6);
                    if (role != null)
                    {
                        SetCookieMember(username, strMd5Server);
                        if (WebConfiguration.CurrentAction == null || WebConfiguration.CurrentController == null)
                        {
                            WebConfiguration.AllowAccessAdminCP = true;
                            return RedirectToAction("Index", "Admin");
                        }
                        return RedirectToAction(WebConfiguration.CurrentAction, WebConfiguration.CurrentController);
                    }
                    else
                    {
                        // Store data to transfer to view
                        ViewData["LoginStatus"] = "Bạn không có quyền truy cập vào trang quản trị..";
                        return View();
                    }
                }
                else
                {
                    // Store data to transfer to view
                    ViewData["LoginStatus"] = "Mật khẩu của thành viên này chưa đúng. Bạn cần kiểm tra lại.";
                    return View();
                }
            }
            else
            {
                // Store data to transfer to view
                ViewData["LoginStatus"] = errText;
                return View();
            }  
        }

        private void SetCookieMember(string username, string password, bool rememberme = true)
        {
            HttpCookie SlmMemberCookie = new HttpCookie("SLMFMembers");
            HttpCookie SlmSessionId = new HttpCookie("SLMFSessionId");
            DateTime dateSLMF = DateTime.Now;
            SlmMemberCookie.Value = username;
            SlmMemberCookie.Expires = dateSLMF.AddDays(3);
            SlmSessionId.Value = password;
            SlmSessionId.Expires = dateSLMF.AddDays(4);
            if (rememberme)
            {
                SlmMemberCookie.Expires = dateSLMF.AddDays(7);
                SlmSessionId.Expires = dateSLMF.AddDays(8);
            }
            Response.Cookies.Add(SlmMemberCookie);
            Response.Cookies.Add(SlmSessionId);
        }

        // **************************************
        // URL: /Account/LogOff
        // **************************************

        public ActionResult LogOff()
        {
            HttpCookie SlmMemberCookie = new HttpCookie("SLMFMembers");
            SlmMemberCookie = Request.Cookies["SLMFMembers"];
            if (SlmMemberCookie != null && SlmMemberCookie.Value != "" &&
                     SlmMemberCookie.Value != null)
            {
                SlmMemberCookie.Expires = new System.DateTime(2005, 1, 1);
                SlmMemberCookie.Value = null;
                Response.Cookies.Add(SlmMemberCookie);
            }
            FormsAuthentication.SignOut();
            if (WebConfiguration.CurrentAction == null || WebConfiguration.CurrentController == null)
            {
                WebConfiguration.AllowAccessAdminCP = false;
                return View("LogOn");
            }
            return RedirectToAction(WebConfiguration.CurrentAction, WebConfiguration.CurrentController);
        }

        // **************************************
        // URL: /Account/ChangePassword
        // **************************************

        [CustomAuthorize]
        public ActionResult ChangePassword()
        {
            ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
            return View();
        }

        [CustomAuthorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult ChangePassword(FormCollection forms)
        {
            var errText = string.Empty;
            string username = LookCookie();
            string oldpassword = forms.GetValues("ChangePassword_OldPassword")[0];
            string newpassword = forms.GetValues("ChangePassword_NewPassword")[0];

            ObjectParameter parpassword = new ObjectParameter("Password", typeof(string));
            ObjectParameter parsalt = new ObjectParameter("Salt", typeof(string));
            ObjectParameter parresult = new ObjectParameter("Result", typeof(int));
            var intResult = DataContext.Instance.selMembersLogin(username, parpassword, parsalt, parresult);
            if (int.Parse(parresult.Value.ToString()) == -1)
            {
                errText = "Tài khoản này không tồn tại. Bạn có thể Đăng ký một Tài khỏan mới";
            }
            else if (int.Parse(parresult.Value.ToString()) == -2)
            {
                errText = "Hệ thống hiện nay chưa cho phép đăng nhập vào diễn đàn.";
            }
            else if (int.Parse(parresult.Value.ToString()) == -3)
            {
                errText = "Tài khoản của bạn đã bị khóa. Bạn không được phép đăng nhập vào diễn đàn.";
            }
            else if (int.Parse(parresult.Value.ToString()) == -5)
            {
                errText = "Tài khoản của bạn chưa kích hoạt. Email kích hoạt Tài khoản đã được gửi đến Email bạn dùng đăng ký.";
            }
            else if (int.Parse(parresult.Value.ToString()) == -4)
            {
                errText = "Tài khoản của bạn cần chờ duyệt trước khi đăng nhập vào diễn đàn.";
            }

            if (errText == string.Empty)
            {
                UtiHashMd5 md5 = new UtiHashMd5();
                // First hash password which user input
                oldpassword = md5.Md5Encode(oldpassword);
                // Then continue hash on above hashed password
                string strMd5Server = md5.Md5Encode(oldpassword + parsalt.Value);
                if (strMd5Server == parpassword.Value.ToString())
                {
                    var user = _repSLM_Members.SelectByUserName(username);
                    if (user != null)
                    {
                        user.Password = md5.Md5Encode(md5.Md5Encode(newpassword) + parsalt.Value);
                        var result = _repSLM_Members.Save();
                        // Update login of user
                        LogoutMember();
                        SetCookieMember(username, user.Password);
                        return RedirectToAction("ChangePasswordSuccess");
                    }
                }
                else
                {
                    // Store data to transfer to view
                    ViewData["LoginStatus"] = "Mật khẩu của thành viên này chưa đúng. Bạn cần kiểm tra lại.";
                    return View();
                }
            }
            else
            {
                // Store data to transfer to view
                ViewData["LoginStatus"] = errText;
                return View();
            } 
            return View();
        }

        private string LookCookie()
        {
            HttpCookie SlmMemberCookie = new HttpCookie("SLMFMembers");
            SlmMemberCookie = Request.Cookies["SLMFMembers"];
            string strUser = "";
            if (SlmMemberCookie != null && SlmMemberCookie.Value != "" &&
                 SlmMemberCookie.Value != null)
            {
                strUser = SlmMemberCookie.Value.ToString();
            }
            return strUser;
        }

        private void LogoutMember()
        {
            HttpCookie SlmMemberCookie = new HttpCookie("SLMFMembers");
            SlmMemberCookie = Request.Cookies["SLMFMembers"];
            if (SlmMemberCookie != null && SlmMemberCookie.Value != "" &&
                     SlmMemberCookie.Value != null)
            {
                SlmMemberCookie.Expires = new System.DateTime(2005, 1, 1);
                SlmMemberCookie.Value = null;
                Response.Cookies.Add(SlmMemberCookie);
            }
            FormsAuthentication.SignOut();
        }

        // **************************************
        // URL: /Account/ChangePasswordSuccess
        // **************************************

        public ActionResult ChangePasswordSuccess()
        {
            return View();
        }

        public ActionResult ResetPassword()
        {
            return View();
        }

        public string GenerateRandomCharacters(int size)
        {
            Random random = new Random((int)DateTime.Now.Ticks);
            StringBuilder builder = new StringBuilder();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }

            return builder.ToString();
        }

        [HttpPost]
        public ActionResult ResetPassword(FormCollection forms)
        {
            var errText = string.Empty;
            var username = forms.GetValues("NguoiDung_UserName")[0];
            var email = forms.GetValues("NguoiDung_Email")[0];

            ObjectParameter parresult = new ObjectParameter("Result", typeof(int));
            ObjectParameter parsalt = new ObjectParameter("Salt", typeof(string));
            ObjectParameter paractivate = new ObjectParameter("Activate", typeof(string));
            ObjectParameter parmemid = new ObjectParameter("MemberId", typeof(int));
            var intResult = DataContext.Instance.selEmailLostPass(username, email, parresult, parsalt, paractivate, parmemid);

            if (int.Parse(parresult.Value.ToString()) == -1)
            {
                errText = "Tài khoản " + username + " không tồn tại";
            }
            else if (int.Parse(parresult.Value.ToString()) == -2)
            {
                errText = "Địa chỉ Email này không đúng với tài khoản : " + username;
            }
            else
            {
                var user = _repSLM_Members.SelectByUserName(username);
                if (user != null)
                {
                    UtiHashMd5 md5 = new UtiHashMd5();
                    var randomStr = GenerateRandomCharacters(10);
                    var newPassword = md5.Md5Encode(md5.Md5Encode(randomStr) + parsalt.Value);
                    user.Password = newPassword;
                    if (_repSLM_Members.Save())
                    {
                        var emailTmp = RenderPartialViewToString("ResetPasswordTemplate");
                        emailTmp = emailTmp.Replace("[Password]", randomStr);
                        if (SendingMail("Reset Password in " + WebConfiguration.SiteName, emailTmp, email))
                        {
                            return RedirectToAction("PasswordResetSuccess");
                        }
                    }
                }
                return RedirectToAction("PasswordResetFailed");
            }

            ViewData["LoginStatus"] = errText;
            return View();
        }

        public ActionResult PasswordResetSuccess()
        {
            return View();
        }

        public ActionResult PasswordResetFailed()
        {
            return View();
        }

    }
}
